// Pure builtins (that is builtins which do not have any side-effects
// outside of the evaluation, with the exception of trace) are
// implemented in this file.
package builtins

import (
	"context"
	"fmt"
	"sync"
	"time"

	"tvl.fyi/tvix/eval/internal/bytecode"
	"tvl.fyi/tvix/eval/value"
)

var pureBuiltins = map[string]baseBuiltin{
	"length": {
		argcount: 1,
		function: func(_ctx context.Context, args []value.NixValue) (value.NixValue, error) {
			l, ok := args[0].(value.NixList)
			if !ok {
				return nil, fmt.Errorf("length: expected a list, but got a %s", args[0].NixType())
			}

			return value.Int(len(l)), nil
		},
	},
}

var PureBuiltins = sync.OnceValue(func() map[string]value.NixValue {
	m := map[string]value.NixValue{
		"currentTime": bytecode.NewNativeThunk(
			sync.OnceValue(func() value.NixValue {
				return value.Int(time.Now().Unix())
			})),
	}

	for k, v := range pureBuiltins {
		v.name = k // for convenience

		m[k] = NixBuiltin{v, nil}
	}

	return m
})
